/*
 * SunSpotApplication.java
 *
 * Created on Feb 15, 2011 9:20:00 PM;
 */

package org.sunspotworld;

import com.sun.spot.core.resources.transducers.II2C;
import com.sun.spot.core.resources.transducers.ISwitch;
import com.sun.spot.core.util.Utils;
import com.sun.spot.edemo.EDemoBoard;
import com.sun.spot.espot.service.BootloaderListenerService;

import java.io.IOException;

import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/**
 * The startApp method of this class is called by the VM to start the
 * application.
 * 
 * The manifest specifies this class as MIDlet-1, which means it will
 * be selected for execution.
 */
public class SunSpotApplication extends MIDlet {

    private ISwitch [] sw = EDemoBoard.getInstance().getSwitches();

    private int accelX;
    private int accelY;
    private int accelZ;

    private int joystickY;
    private int joystickX;

    private int cButton;
    private int zButton;

    private II2C connection = EDemoBoard.getInstance().getI2C();

    private byte writeAddress = (byte)0xA4;
    private byte readAddress = (byte)0xA5;
    private byte memoryAddress = (byte)0x40;
    private byte blankByte = (byte)0x00;

    protected void startApp() throws MIDletStateChangeException {
        BootloaderListenerService.getInstance().start();   // monitor the USB (if connected) and recognize commands from host

        System.out.println(">>> Initializing connection with device.");
        boolean ready = initConnection();

        if(ready) {
            sendRequest();
            System.out.println(">>> Data log:");
            System.out.println("Accel x | Accel y | Accel z | z pressed | c pressed | x axis | y axis");
            while(sw[0].isOpen() && sw[1].isOpen()) {
                getData();
                System.out.print(getAccelX() + " ");
                System.out.print(getAccelY() + " ");
                System.out.print(getAccelZ() + " ");
                System.out.print(isZPressed() + " ");
                System.out.print(isCPressed() + " ");
                System.out.print(getXPosition() + " ");
                System.out.print(getYPosition() + "\n");
                Utils.sleep(1);
            }
        }
        else {
            System.out.println(">>> Connection with device not responding.");
        }
        System.out.println(">>> Now exiting application.");

        notifyDestroyed();                      // cause the MIDlet to exit
    }

    private boolean initConnection() {

        boolean initialized = true;
        byte [] initData = {blankByte};
        try {
            connection.open();
            while(connection.isBusy()) {
                //do nothing
            }

            //connection.setClockSpeed(400000);
            while(connection.isBusy()) {
                //do nothing
            }

            connection.write(writeAddress, memoryAddress, 1, initData, 0, initData.length);
            while(connection.isBusy()) {

            }

            initialized = connection.probe(writeAddress, 0x00);

        } catch(IOException e) {
            e.printStackTrace();
        }
        return initialized;
    }

    private void getData() {
        byte [] receive = new byte[6];

        try {
            connection.read(readAddress, receive, 0, receive.length);

            while(connection.isBusy()) {

            }

        } catch(IOException e) {
            e.printStackTrace();
        }

        sendRequest();


        for(int i = 0; i < receive.length; i++) {
            receive[i] = (byte)((receive[i] ^ 0x17) + 0x17);
        }

        joystickX = (int)receive[0] & 0xFF;
        joystickY = (int)receive[1] & 0xFF;

        accelX = (int)(receive[2] & 0xFF) * 2 * 2;
        accelY = (int)(receive[3] & 0xFF) * 2 * 2;
        accelZ = (int)(receive[4] & 0xFF) * 2 * 2;

        zButton = 1;
        cButton = 1;

        if (((receive[5] >> 0) & 1) == 0)
            zButton = 0;

        if (((receive[5] >> 1) & 1) == 0)
            cButton = 0;

        if (((receive[5] >> 2) & 1) == 1)
            accelX += 2;

        if (((receive[5] >> 3) & 1) == 1)
            accelX += 1;

        if (((receive[5] >> 4) & 1) == 1)
            accelY += 2;

        if (((receive[5] >> 5) & 1) == 1)
            accelY += 1;

        if (((receive[5] >> 6) & 1) == 1)
            accelZ += 2;

        if (((receive[5] >> 7) & 1) == 1)
            accelZ += 1;


    }

    private int getAccelX() {
        return accelX;
    }

    private int getAccelY() {
        return accelY;
    }

    private int getAccelZ() {
        return accelZ;
    }

    private boolean isZPressed() {
        //true if pressed, false if released
        if(zButton == 1) {
            return false;
        }
        else {
            return true;
        }
    }

    private boolean isCPressed() {
        //true if pressed, false if released
        if(cButton == 1) {
            return false;
        }
        else {
            return true;
        }
    }

    private int getYPosition() {
        return joystickY;
    }

    private int getXPosition() {
        return joystickX;
    }

    private void sendRequest() {
        byte [] send = new byte[1];
        send[0] = blankByte;
        try {
            connection.write(writeAddress, send, 0, send.length);

            while(connection.isBusy()) {
                //do nothing
            }
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    private void closeConnection() {
        try {
            connection.close();
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    protected void pauseApp() {
        // This is not currently called by the Squawk VM
    }

    /**
     * Called if the MIDlet is terminated by the system.
     * It is not called if MIDlet.notifyDestroyed() was called.
     *
     * @param unconditional If true the MIDlet must cleanup and release all resources.
     */
    protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
    }
}
